package com.bix.util.blizfiles.dds;

import java.nio.ByteBuffer;


class DDSAlphaBlock3BitLinear {
	private byte alpha0;
	private byte alpha1;
	private byte[] stuff = new byte[6];

	public DDSAlphaBlock3BitLinear() {
	}

	public DDSAlphaBlock3BitLinear(ByteBuffer bb) {
		this.alpha0 = bb.get();
		this.alpha1 = bb.get();
		bb.get(this.stuff);
	}

	/**
	 * @return the alpha0
	 */
	public byte getAlpha0 () {
		return alpha0;
	}

	/**
	 * @param alpha0 the alpha0 to set
	 */
	public void setAlpha0 (byte alpha0) {
		this.alpha0 = alpha0;
	}

	/**
	 * @return the alpha1
	 */
	public byte getAlpha1 () {
		return alpha1;
	}

	/**
	 * @param alpha1 the alpha1 to set
	 */
	public void setAlpha1 (byte alpha1) {
		this.alpha1 = alpha1;
	}

	/**
	 * @return the stuff
	 */
	public byte[] getStuff () {
		return stuff;
	}

	/**
	 * @param stuff the stuff to set
	 */
	public void setStuff (byte[] stuff) {
		this.stuff = stuff;
	}

	public void decode (int destination[], int offset, int width, DDSColorAlpha alphaZero) {
		byte[][]	bits = new byte[4][4];
		short[]		alphas = new short[8];
		
		/* get initial alphas */
		alphas[0] = this.getAlpha0();
		alphas[1] = this.getAlpha1();

		/* 8-alpha block */
		if (alphas[0] > alphas[1]) {
			/* 000 = alpha_0, 001 = alpha_1, others are interpolated */
			alphas[2] = (short)(( 6 * alphas[0] +     alphas[1]) / 7);	/* bit code 010 */
			alphas[3] = (short)(( 5 * alphas[0] + 2 * alphas[1]) / 7);	/* bit code 011 */
			alphas[4] = (short)(( 4 * alphas[0] + 3 * alphas[1]) / 7);	/* bit code 100 */
			alphas[5] = (short)(( 3 * alphas[0] + 4 * alphas[1]) / 7);	/* bit code 101 */
			alphas[6] = (short)(( 2 * alphas[0] + 5 * alphas[1]) / 7);	/* bit code 110 */
			alphas[7] = (short)((     alphas[0] + 6 * alphas[1]) / 7);	/* bit code 111 */
		}
		/* 6-alpha block */
		else
		{ 
			/* 000 = alpha_0, 001 = alpha_1, others are interpolated */
			alphas[2] = (short)((4 * alphas[0] +     alphas[1]) / 5);	/* bit code 010 */
			alphas[3] = (short)((3 * alphas[0] + 2 * alphas[1]) / 5);	/* bit code 011 */
			alphas[4] = (short)((2 * alphas[0] + 3 * alphas[1]) / 5);	/* bit code 100 */
			alphas[5] = (short)((    alphas[0] + 4 * alphas[1]) / 5);	/* bit code 101 */
			alphas[6] = 0;																						/* bit code 110 */
			alphas[7] = 255;																					/* bit code 111 */
		}
		
		/* decode 3-bit fields into array of 16 bytes with same value */
		
		/* first two rows of 4 pixels each */
		long	stuff;
		stuff  =  (long)(this.getStuff()[0] & 0xFF);
		stuff |= ((long)(this.getStuff()[1]) & 0xFF) << 8;
		stuff |= ((long)(this.getStuff()[2]) & 0xFF) << 16;
		stuff |= ((long)(this.getStuff()[3]) & 0xFF) << 24;		
		
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < 4; j++) {
				bits[i][j] = (byte) (stuff & 0x00000007);
				stuff >>= 3;
			}
		}
		
		/* last two rows */
		stuff = (long)(this.getStuff()[3] & 0xFF);
		stuff |= ((long)(this.getStuff()[4]) & 0xFF) << 8;
		stuff |= ((long)(this.getStuff()[5]) & 0xFF) << 16; /* last 3 bytes */
		
		for (int i = 2; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				bits[i][j] = (byte) (stuff & 0x00000007);
				stuff >>= 3;
			}
		}
		
		/* decode the codes into alpha values */
		DDSColorAlpha[][]	aColors = new DDSColorAlpha[4][4];
		for (int row = 0; row < 4; row++ ) {
			for (int pix=0; pix < 4; pix++ ) {
				// aColors[row][pix] = new DDSColorAlpha (0, 0, 0, alphas[bits[row][pix]]);
				/* TODO */
			}
		}
		
		/* write out alpha values to the image bits */
		for (int row = 0; row < 4; row++, offset += width-4 ) {
			for (int pix = 0; pix < 4; pix++ ) {
				/* zero the alpha bits of image pixel */
				destination[offset] &= alphaZero.getAsInteger();
				
				/* or the bits into the prev. nulled alpha */
				destination[offset++] |= aColors[row][pix].getAsInteger();
			}
		}		
	}
}

